package Task;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * BIO:阻塞式IO，读写过程中可能存在阻塞现象（卡住程序）
 * NIO:非阻塞式IO,读写过程不会出现阻塞现象.
 */
public class NIODemo1 {
    public static void main(String[] args) throws IOException {
        //BIO的写法
//        FileInputStream fis = new FileInputStream("movie.wmv");
//        FileOutputStream fos = new FileOutputStream("movie_cp.wmv");
//
//        //块读写赋值
//        int len;//记录每次实际读取的字节数
//        byte[] buf = new byte[1024*10];//10k缓冲区
//        while((len = fis.read(buf))!=-1){
//            fos.write(buf,0,len);
//        }
//        System.out.println("复制完毕!");
//        fis.close();
//        fos.close();




        //NIO写法
        /*
            BIO是面向流的.NIO是面向通道的.
            流是单向的,要么用于度(输入),要么用于写(输出)
            NIO是面向通道的,通道是双向的,又能读又能写
            Channel是通道,常见的通道有很多:
            FileChannel:操作文件的通道,可对文件进行读写操作
            SocketChannel:套接字通道,可与远端计算机进行TCP的双向读写操作
            ServerSocketChannel:服务端套接字通道,用于监听客户端的链接
         */
        FileInputStream fis =new FileInputStream("movie.wmv");
        FileChannel inChannel =fis.getChannel();//通过该文件输入流获取操作movie.wmv通道
        FileOutputStream fos = new FileOutputStream("movie_cp.wmv");
        FileChannel outChannel = fos.getChannel();//通过该文件输出流获取操作movie_cp.wmv通道


        //块读写赋值
        int len ;//记录每次读到的字节数
        ByteBuffer buffer =ByteBuffer.allocate(1024*10);//开辟一个10k的缓存区.
        //一次性通过inChannel从源文件读取10k放到缓存区.
        /*
            read前buffer:
            position:0
            limit:10240
         */

        while((inChannel.read(buffer))!=-1){
            /*
                read后buffer:
                position:10240
                limit:10240
             */

            buffer.flip();
            /*
                flip后buffer  1:limit=position 2:position=0
                position:0
                limit:10240
             */
            /*
                write(ByteBuffer buf)
                将buf中position-limit之间所有的数据一次性写出
             */
            outChannel.write(buffer);
            /*
                write后buffer:
                position:10240
                limit:10240
             */

            buffer.clear();//clear()的作用1:limit为buffer容量   2:position为0
            /*
                clear后buffer:
                position:0
                limit:10240
             */

        }
        System.out.println("复制完毕!");
        fis.close();
        fos.close();
        inChannel.close();





    }
}
